home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / pc / PINBSRC.ZIP / AUDIOTPU.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1996-02-02  |  27.4 KB  |  939 lines

  1. { AUDIOTPU.PAS  - (c) Ansgar Scherp, Joachim Gelhaus
  2.   All rights reserved / vt'95 }
  3.  
  4. {$A+,B+,D+,E+,F-,G+,I+,L+,N-,O-,P-,Q+,R-,S+,T-,V+,X+,Y+}
  5. {$M 16384,0,655360}
  6.  
  7. UNIT AUDIOTPU;
  8.  
  9. INTERFACE
  10.  
  11. USES Dos, Crt { Delay };
  12.  
  13.  
  14. var  maxTitles : integer; {jo INTEGER!!}
  15.  
  16. CONST
  17.   NOT_CHANGED        = $01;
  18.   IOO_CLOSE_TRAY     = 5;
  19.   LOCK               = $01;
  20.   SEEK_1             = 131;
  21.   DIGITALCOPY        = $20;
  22.   DEV_CLOSE          = 14;
  23.   HAS_CHANGED        = $FF;
  24.   STOP_AUDIO         = 133;
  25.   IOI_SECT_SIZE      = 7;
  26.   IOCTL_INP          = 3;
  27.   IOCTL_OUTP         = 12;
  28.   EMPHASIS           = $10;
  29.   FOURTRACK          = $80;
  30.   DOOR_OPEN          = $001{L};
  31.   DATA_AND_AUDIO     = $010{L};
  32.   DOOR_UNLOCKED      = $002{L};
  33.   TWOTRACK           = $00;
  34.   PREFETCHING        = $080{L};
  35.   UNLOCK             = $00;
  36.   DEV_OPEN           = 13;
  37.   HSG_AND_RED        = $200{L};
  38.   INTERLEAVING       = $020{L};
  39.   WRITE_LONG         = 134;
  40.   IOI_DRIVE_BYTES    = 5;
  41.   IOI_QCHAN_INFO     = 12;
  42.   READ_LONG          = 128;
  43.   DONT_KNOW          = $00;
  44.   RESUME_AUDIO       = 136;
  45.   IOI_UPC            = 14;
  46.   DATA               = $40;
  47.   IOI_AUDIO_INFO     = 10;
  48.   AUDIO_MANIPULATION = $100{L};
  49.   IOO_EJECT          = 0;
  50.   IOI_VOL_SIZE       = 8;
  51.   IOI_DEV_STAT       = 6;
  52.   IOI_LOC_HEAD       = 1;
  53.   IOI_DRV_HEAD       = 0;
  54.   IOI_MEDIA_CHANG    = 9;
  55.   WRITE_LONG_VERIFY  = 135;
  56.   IOI_AUDIO_STATUS   = 15;
  57.   PLAY_AUDIO         = 132;
  58.   IOO_LOCK           = 1;
  59.   IOO_AUDIOCHAN_CTRL = 3;
  60.   IOI_AUDIOCHAN_INFO = 4;
  61.   COOKED_AND_RAW     = $004{L};
  62.   Red                = 1;
  63.   READ_WRITE         = $008{L};
  64.   IOI_TRACK_INFO     = 11;
  65.   READ_LONG_PREFETCH = 130;
  66.   INIT               = 0;
  67.   HSG                = 0;
  68.   IOO_RESET          = 2;
  69.   OUTPUT_FLUSH       = 8;
  70.   INPUT_FLUSH        = 7;
  71.  
  72. TYPE
  73.   CD_Addr = RECORD CASE INTEGER OF
  74.     0 : (HSG_Sector : WORD);
  75.     1 : (Time       : RECORD
  76.                         Frame  : BYTE;
  77.                         Second : BYTE;
  78.                         Minute : BYTE;
  79.                         Unused : BYTE;
  80.                       END);
  81.   END;
  82.  
  83.   pInteger = ^INTEGER;
  84.  
  85.   Audio_Status = RECORD
  86.     Status : WORD;
  87.     Start  : CD_Addr;
  88.     End_1  : CD_Addr;
  89.   END;
  90.  
  91.   Request_Hdr = RECORD
  92.     rq_Len    : BYTE;
  93.     rq_Unit   : BYTE;
  94.     rq_Cmd    : BYTE;
  95.     rq_Status : WORD;
  96.     Reserved  : ARRAY [0..7] OF BYTE;
  97.   END;
  98.  
  99.   QChannel_Info = RECORD
  100.     Tno    : BYTE; { Track }
  101.     x      : BYTE;
  102.     tMin   : BYTE;
  103.     tSec   : BYTE;
  104.     tFrame : BYTE;
  105.     Zero   : BYTE;
  106.     dMin   : BYTE;
  107.     dSec   : BYTE;
  108.     dFrame : BYTE;
  109.   END;
  110.  
  111.   Audio_Play_Request = RECORD
  112.     Play_rqh  : Request_Hdr;
  113.     Addr_Mode : BYTE;         { RED or HSG }
  114.     Start     : CD_Addr;      { Startframe }
  115.     nFrames   : LONGINT;
  116.   END;
  117.  
  118.   IO_Inp_Audio_Status = RECORD
  119.     IOctl_Cmd : BYTE;
  120.     Report    : Audio_Status;
  121.   END;
  122.  
  123.   IO_Inp_Track_Info = RECORD
  124.     IOctl_Cmd : BYTE;
  125.     Tno       : BYTE;
  126.     Start     : CD_Addr;
  127.     Control   : BYTE;
  128.   END;
  129.   { control:
  130.               TWOTRACK      $0
  131.               FOURTRACK     $80
  132.               EMPHASIS      $10
  133.               DATA          $40
  134.               DIGITALCOPY   $20 }
  135.  
  136.   IO_Inp_Audio_Info = RECORD
  137.     IOctl_Cmd      : BYTE;
  138.     Track_Lo       : BYTE;
  139.     Track_Hi       : BYTE;
  140.     Track_Lead_Out : CD_Addr;
  141.   END;
  142.  
  143.   IOCTL_Inp_Request = RECORD
  144.     IOctl_Rqh    : Request_Hdr;
  145.  
  146.     IOctl_Media  : BYTE;
  147.     IOCtl_xFer   : pInteger;
  148.     IOCtl_nBytes : WORD;
  149.     IOctl_Sector : WORD;
  150.     IOctl_VolID  : pInteger;
  151.   END;
  152.  
  153.   Track_Info_Tag = RECORD
  154.     Start  : CD_Addr;
  155.     Frames : LONGINT;
  156.     Delta  : CD_Addr;
  157.   END;
  158.  
  159.   A_TrackInfoTag_99 = ARRAY [0..98] OF Track_Info_Tag;
  160.  
  161.   IO_Inp_Device_Status = RECORD
  162.     IOctl_Cmd : BYTE;
  163.     Status    : WORD;
  164.   END;
  165.  
  166.   IO_Inp_UPC = RECORD
  167.     IOctl_Cmd : BYTE;
  168.     Addr_Mode : BYTE;
  169.     Signature : ARRAY [0..13] OF CHAR;
  170.     aFrame    : BYTE;                  { ????? }
  171.   END;
  172.  
  173.   IO_Inp_Device_Hdr = RECORD
  174.     IOctl_Cmd  : BYTE;
  175.     Device_Hdr : pInteger;
  176.   END;
  177.  
  178.   IO_Inp_Media_Changed = RECORD
  179.     IOctl_Cmd  : BYTE;
  180.     Media_Byte : BYTE;
  181.   END;
  182.  
  183.   IO_Inp_QChannel = RECORD
  184.     IOctl_Cmd : BYTE;
  185.     Addr_Mode : BYTE;
  186.     qInfo     : QChannel_Info;
  187.   END;
  188.  
  189.   IO_Outp_Eject = RECORD
  190.     IOctl_Cmd : BYTE;
  191.   END;
  192.  
  193.   IO_Inp_Audiochan_Info = RECORD
  194.     IOctl_Cmd : BYTE;
  195.     Inp_Chan0 : BYTE;
  196.     Vol_Chan0 : BYTE;
  197.     Inp_Chan1 : BYTE;
  198.     Vol_Chan1 : BYTE;
  199.     Inp_Chan2 : BYTE;
  200.     Vol_Chan2 : BYTE;
  201.     Inp_Chan3 : BYTE;
  202.     Vol_Chan3 : BYTE;
  203.   END;
  204.  
  205.   IO_Outp_Lock_Door = RECORD
  206.     IOctl_Cmd  : BYTE;
  207.     Function_1 : BYTE;
  208.   END;
  209.  
  210.   IO_Inp_Volume_Size = RECORD
  211.     IOctl_Cmd : BYTE;
  212.     HSG_Sect  : WORD;
  213.   END;
  214.  
  215.   IO_Inp_Sector_Size = RECORD
  216.     IOctl_Cmd : BYTE;
  217.     Addr_Mode : BYTE;
  218.     Sect_Size : WORD;
  219.   END;
  220.  
  221.   IO_Inp_Drive_Bytes = RECORD
  222.     IOctl_Cmd  : BYTE;
  223.     Bytes2read : BYTE;
  224.     Read_Buff  : ARRAY [0..127] OF BYTE;
  225.   END;
  226.  
  227.   IO_Inp_Head_Loc = RECORD
  228.     IOctl_Cmd : BYTE;
  229.     Addr_Mode : BYTE;
  230.     Location  : WORD;
  231.   END;
  232.  
  233. CONST
  234.   rq_Input : IO_Inp_Audiochan_Info = (
  235.     IOctl_Cmd : 0;
  236.     Inp_Chan0 : 0;
  237.     Vol_Chan0 : 0;
  238.     Inp_Chan1 : 0;
  239.     Vol_Chan1 : 0;
  240.     Inp_Chan2 : 0;
  241.     Vol_Chan2 : 0;
  242.     Inp_Chan3 : 0;
  243.     Vol_Chan3 : 0);
  244.  
  245.   rq_Volume : IO_Inp_Audiochan_Info = (
  246.     IOctl_Cmd : 0;
  247.     Inp_Chan0 : 0;
  248.     Vol_Chan0 : 0;
  249.     Inp_Chan1 : 0;
  250.     Vol_Chan1 : 0;
  251.     Inp_Chan2 : 0;
  252.     Vol_Chan2 : 0;
  253.     Inp_Chan3 : 0;
  254.     Vol_Chan3 : 0);
  255.  
  256.   rq_Insert : IO_Outp_Eject = (IOctl_Cmd : 0);
  257.  
  258.   rq_Eject  : IO_Outp_Eject = (IOctl_Cmd : 0);
  259.  
  260.   rq_Reset  : IO_Outp_Eject = (IOctl_Cmd : 0);
  261.  
  262.   rq_QChan  : IO_Inp_QChannel = (
  263.     IOctl_Cmd : 0;
  264.     Addr_Mode : 0;
  265.     qInfo     : (
  266.       Tno    : 0;
  267.       x      : 0;
  268.       tMin   : 0;
  269.       tSec   : 0;
  270.       tFrame : 0;
  271.       Zero   : 0;
  272.       dMin   : 0;
  273.       dSec   : 0;
  274.       dFrame : 0));
  275.  
  276.   Index : A_TrackInfoTag_99 = (
  277.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  278.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  279.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  280.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  281.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  282.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  283.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  284.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  285.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  286.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  287.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  288.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  289.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  290.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  291.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  292.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  293.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  294.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  295.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  296.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  297.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  298.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  299.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  300.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  301.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  302.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  303.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  304.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  305.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  306.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  307.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  308.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  309.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  310.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  311.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  312.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  313.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  314.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  315.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  316.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  317.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  318.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  319.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  320.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  321.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  322.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  323.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  324.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  325.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  326.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  327.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  328.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  329.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  330.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  331.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  332.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  333.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  334.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  335.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  336.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  337.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  338.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  339.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  340.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  341.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  342.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  343.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  344.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  345.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  346.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  347.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  348.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  349.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  350.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  351.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  352.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  353.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  354.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  355.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  356.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  357.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  358.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  359.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  360.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  361.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  362.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  363.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  364.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  365.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  366.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  367.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  368.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  369.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  370.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  371.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  372.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  373.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  374.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0)),
  375.     (Start:(HSG_Sector: 0);Frames:0;Delta:(HSG_Sector : 0))
  376.   );
  377.  
  378.   Start_Play : LONGINT = 0;
  379.   End_Play   : LONGINT = 0;
  380.  
  381.   qInfo : QChannel_Info = (
  382.     Tno    : 0;
  383.     x      : 0;
  384.     tMin   : 0;
  385.     tSec   : 0;
  386.     tFrame : 0;
  387.     Zero   : 0;
  388.     dMin   : 0;
  389.     dSec   : 0;
  390.     dFrame : 0);
  391.  
  392.   Audio_Drive : WORD = 0;
  393.   Titles      : BYTE = 0;
  394.  
  395.   rqInp : IOCTL_Inp_Request = (
  396.     IOctl_Rqh : (
  397.       rq_Len    : SizeOf(IOCTL_Inp_Request);
  398.       rq_Unit   : 0;
  399.       rq_Cmd    : IOCTL_INP;
  400.       rq_Status : 0;
  401.       Reserved  : (0,0,0,0,0,0,0,0));
  402.     IOctl_Media  : 0;
  403.     IOCtl_xFer   : NIL;
  404.     IOCtl_nBytes : 0;
  405.     IOctl_Sector : 0;
  406.     IOctl_VolID  : NIL);
  407.  
  408.   rq_Status : IO_Inp_Device_Status = (
  409.     IOctl_Cmd : IOI_DEV_STAT;
  410.     Status    : 0);
  411.  
  412.   rq_UPC : IO_Inp_UPC = (
  413.     IOctl_Cmd : IOI_UPC;
  414.     Addr_Mode : Red;
  415.     Signature : (#0,#0,#0,#0,#0,#0,#0,#0,#0,#0,#0,#0,#0,#0);
  416.     aFrame    : 0);
  417.  
  418.   rq_Header : IO_Inp_Device_Hdr = (
  419.     IOctl_Cmd  : IOI_DRV_HEAD;
  420.     Device_Hdr : NIL);
  421.  
  422.   rq_Busy : IO_Inp_Device_Hdr = (
  423.     IOctl_Cmd  : IOI_DRV_HEAD;
  424.     Device_Hdr : NIL);
  425.  
  426.   rq_Audio_Status : IO_Inp_Audio_Status = (
  427.     IOctl_Cmd : IOI_AUDIO_STATUS;
  428.     Report    : (
  429.       Status : 0;
  430.       Start  : (HSG_Sector : 0);
  431.       End_1  : (HSG_Sector : 0)));
  432.  
  433.   rq_Media : IO_Inp_Media_Changed = (
  434.     IOctl_Cmd  : IOI_MEDIA_CHANG;
  435.     Media_Byte : 0);
  436.  
  437.   rqOutp : IOCTL_Inp_Request = (
  438.     IOctl_Rqh   : (
  439.       rq_Len    : SizeOf(IOCTL_Inp_Request);
  440.       rq_Unit   : 0;
  441.       rq_Cmd    : IOCTL_OUTP;
  442.       rq_Status : 0;
  443.       Reserved  : (0,0,0,0,0,0,0,0));
  444.     IOctl_Media  : 0;
  445.     IOCtl_xFer   : NIL;
  446.     IOCtl_nBytes : 0;
  447.     IOctl_Sector : 0;
  448.     IOctl_VolID  : NIL);
  449.  
  450.   rq_Play : Audio_Play_Request = (
  451.     Play_rqh : (
  452.       rq_Len    : SizeOf(Audio_Play_Request);
  453.       rq_Unit   : 0;
  454.       rq_Cmd    : PLAY_AUDIO;
  455.       rq_Status : 0;
  456.       Reserved  : (0,0,0,0,0,0,0,0));
  457.     Addr_Mode : Red;
  458.     Start     : (HSG_Sector : 0);
  459.     nFrames   : 0);
  460.  
  461.   rq_Stop : Audio_Play_Request = (
  462.     Play_rqh : (
  463.       rq_Len    : SizeOf(Request_Hdr);
  464.       rq_Unit   : 0;
  465.       rq_Cmd    : STOP_AUDIO;
  466.       rq_Status : 0;
  467.       Reserved  : (0,0,0,0,0,0,0,0));
  468.     Addr_Mode : Red;
  469.     Start     : (HSG_Sector : 0);
  470.     nFrames   : 0);
  471.  
  472.   rq_Resume : Audio_Play_Request = (
  473.     Play_rqh : (
  474.       rq_Len    : SizeOf(Request_Hdr);
  475.       rq_Unit   : 0;
  476.       rq_Cmd    : RESUME_AUDIO;
  477.       rq_Status : 0;
  478.       Reserved  : (0,0,0,0,0,0,0,0));
  479.     Addr_Mode : Red;
  480.     Start     : (HSG_Sector : 0);
  481.     nFrames   : 0);
  482.  
  483.   FUNCTION Red2HSG(Time : CD_Addr) : LONGINT;
  484.   PROCEDURE HSG2Red(nSect : LONGINT; VAR Local : CD_Addr);
  485.   FUNCTION IOctl_In(Drive    : WORD;
  486.                     Unit_1   : BYTE;
  487.                     pRequest : pInteger;
  488.                     rqLen    : WORD) : WORD;
  489.   FUNCTION Get_Status(Drive : CHAR) : WORD;
  490.   PROCEDURE Get_UPC(VAR UPC : STRING);
  491.   FUNCTION Get_Header : pInteger;
  492.   FUNCTION Audio_Busy : WORD;
  493.   PROCEDURE Read_Audio_Status(VAR Status : Audio_Status);
  494.   FUNCTION Get_Media_Changed : BYTE;
  495.   FUNCTION Get_TOC : BYTE;
  496.   FUNCTION Audio_Pause : WORD;
  497.   FUNCTION Get_Track_Info(Tno : BYTE) : BYTE;
  498.   PROCEDURE Read_QChannel(VAR QC : QChannel_Info);
  499.   FUNCTION IOctl_Out(Drive    : WORD;
  500.                      Unit_1   : BYTE;
  501.                      pRequest : pInteger;
  502.                      rqLen    : WORD) : WORD;
  503.   PROCEDURE CD_Reset;
  504.   PROCEDURE Eject_CD;
  505.   PROCEDURE Insert_CD;
  506.   PROCEDURE SetVolume(Chan0, Chan1, Chan2, Chan3 : BYTE);
  507.   PROCEDURE SetInput(Chan0, Chan1, Chan2, Chan3 : BYTE);
  508.   FUNCTION Play_Audio_1(Start    : CD_Addr;
  509.                         nSectors : LONGINT) : WORD;
  510.   FUNCTION Play_Track(Tno : BYTE) : BOOLEAN;
  511.   FUNCTION Play_Tracks(From, To_1 : LONGINT) : BOOLEAN;
  512.   FUNCTION Play_Track_Intro(Tno : INTEGER) : BOOLEAN;
  513.   FUNCTION Stop_Audio_1 : WORD;
  514.   FUNCTION Resume_Audio_1 : WORD;
  515.   FUNCTION Skip_Audio(Frames : LONGINT) : WORD;
  516.   FUNCTION Init_CDAudio : INTEGER;
  517.   FUNCTION Get_Titles : BYTE;
  518.   PROCEDURE Get_Len(Tno : CHAR; VAR Len : CD_Addr);
  519.   FUNCTION Get_Actual_Track : INTEGER;
  520.   PROCEDURE Get_Time_In_Track(T : QChannel_Info);
  521.   FUNCTION Get_Audio_Drive : CHAR;
  522.  
  523. IMPLEMENTATION
  524.  
  525.   FUNCTION Red2HSG(Time : CD_Addr) : LONGINT;
  526.   BEGIN
  527.     Red2HSG := LONGINT ( LONGINT(Time.Time.Minute) * 4500 +
  528.                          LONGINT(Time.Time.Second) *   75 +
  529.                          LONGINT(Time.Time.Frame) );
  530.   END;
  531.  
  532.   PROCEDURE HSG2Red(nSect : LONGINT; VAR Local : CD_Addr);
  533.   BEGIN
  534.     Local.Time.Frame  := nSect MOD 75;
  535.     nSect             := nSect DIV 75;
  536.     Local.Time.Second := nSect MOD 60;
  537.     Local.Time.Minute := nSect DIV 60;
  538.   END;
  539.  
  540.   FUNCTION IOctl_In(Drive    : WORD;
  541.                     Unit_1   : BYTE;
  542.                     pRequest : pInteger;
  543.                     rqLen    : WORD) : WORD;
  544.   VAR
  545.     Regs : Registers;
  546.   BEGIN
  547.     rqInp.IOCtl_nBytes      := rqLen;
  548.     rqInp.IOCtl_xFer        := pInteger(pRequest);
  549.     rqInp.IOctl_Rqh.rq_Unit := Unit_1;
  550.  
  551.     Regs.AX := $1510; { send device request }
  552.     Regs.CX := Drive;
  553.     Regs.BX := Ofs(rqInp);
  554.     Regs.ES := Seg(rqInp);
  555.     Intr($2F, Regs);
  556.     IOctl_In := (rqInp.IOctl_Rqh.rq_Status);
  557.   END;
  558.  
  559.   FUNCTION Get_Status(Drive : CHAR) : WORD;
  560.   BEGIN
  561.     IF (IOctl_In(INTEGER(Drive), 0, @rq_Status,
  562.                  SizeOf(IO_Inp_Device_Status))
  563.                  AND $8000) <> 0 THEN BEGIN
  564.       Get_Status := ($FFFF);
  565.       Exit;
  566.     END ELSE BEGIN
  567.       Get_Status := (rq_Status.Status);
  568.       Exit;
  569.     END;
  570.   END;
  571.  
  572.   PROCEDURE Get_UPC(VAR UPC : STRING);
  573.   VAR
  574.     I : INTEGER;
  575.   BEGIN
  576.     IOctl_In(Audio_Drive, 0, @rq_UPC, SizeOf(IO_Inp_UPC));
  577.     FOR I := 0 TO 7 DO
  578.       UPC[I+1] := rq_UPC.Signature[I];
  579.   END;
  580.  
  581.  FUNCTION Get_Header : pInteger;
  582.   BEGIN
  583.     IOctl_In(Audio_Drive, 0, @rq_Header,
  584.              SizeOf(IO_Inp_Device_Hdr));
  585.     Get_Header := (rq_Header.Device_Hdr);
  586.   END;
  587.  
  588.   FUNCTION Audio_Busy : WORD;
  589.   BEGIN
  590.     Audio_Busy := (IOctl_In(Audio_Drive, 0, @rq_Busy,
  591.                    SizeOf(IO_Inp_Device_Hdr)) AND $8200);
  592.   END;
  593.  
  594.   PROCEDURE Read_Audio_Status(VAR Status : Audio_Status);
  595.   BEGIN
  596.     IOctl_In(Audio_Drive, 0, @rq_Audio_Status,
  597.              SizeOf(IO_Inp_Audio_Status));
  598.     Status := (rq_Audio_Status.Report);
  599.   END;
  600.  
  601.   FUNCTION Get_Media_Changed : BYTE;
  602.   BEGIN
  603.     IOctl_In(Audio_Drive, 0, @rq_Media,
  604.              SizeOf(IO_Inp_Media_Changed));
  605.     Get_Media_Changed := (rq_Media.Media_Byte);
  606.   END;
  607.  
  608.   FUNCTION Get_TOC : BYTE;
  609.   VAR
  610.     rq_TOC   : IO_Inp_Audio_Info;
  611.     rq_Track : IO_Inp_Track_Info;
  612.     I        : INTEGER;
  613.   BEGIN
  614.     rq_TOC.IOctl_Cmd := IOI_AUDIO_INFO;
  615.     IOctl_In(Audio_Drive, 0, @rq_TOC,
  616.              SizeOf(IO_Inp_Audio_Info));
  617.     rq_Track.IOctl_Cmd := IOI_TRACK_INFO;
  618.     I := INTEGER(rq_TOC.Track_Lo);
  619.     WHILE (I <= INTEGER(rq_TOC.Track_Hi)) DO BEGIN
  620.       rq_Track.Tno := I;
  621.       IOctl_In(Audio_Drive, 0, @rq_Track,
  622.                SizeOf(IO_Inp_Track_Info));
  623.       Index[I].Start    := rq_Track.Start;
  624.       Index[I-1].Frames := Red2HSG(Index[I].Start) -
  625.                            Red2HSG(Index[I-1].Start);
  626.       HSG2Red(Index[I-1].Frames, Index[I-1].Delta);
  627.       I := Succ(I);
  628.     END;
  629.     Index[I-1].Frames := Red2HSG(rq_TOC.Track_Lead_Out) -
  630.                          Red2HSG(Index[I-1].Start);
  631.     HSG2Red(Index[I-1].Frames, Index[I-1].Delta);
  632.     Index[0].Start  := Index[1].Start;
  633.     Index[0].Frames := Red2HSG(rq_TOC.Track_Lead_Out) -
  634.                        Red2HSG(Index[1].Start);
  635.     HSG2Red(Index[0].Frames, Index[0].Delta);
  636.     Get_TOC := (rq_TOC.Track_Hi);
  637.   END;
  638.  
  639.   FUNCTION Audio_Pause : WORD;
  640.   VAR
  641.     rq_Audio_Status : IO_Inp_Audio_Status;
  642.   BEGIN
  643.     rq_Audio_Status.IOctl_Cmd := IOI_AUDIO_STATUS;
  644.     IOctl_In(Audio_Drive, 0, @rq_Audio_Status,
  645.              SizeOf(IO_Inp_Audio_Status));
  646.     Audio_Pause := (rq_Audio_Status.Report.Status AND $01);
  647.   END;
  648.  
  649.   FUNCTION Get_Track_Info(Tno : BYTE) : BYTE;
  650.   VAR
  651.     rq_Track : IO_Inp_Track_Info;
  652.   BEGIN
  653.     rq_Track.IOctl_Cmd := IOI_TRACK_INFO;
  654.     rq_Track.Tno       := Tno;
  655.     IOctl_In(Audio_Drive, 0, @rq_Track,
  656.              SizeOf(IO_Inp_Track_Info));
  657.     Get_Track_Info := (rq_Track.Control);
  658.   END;
  659.  
  660.   PROCEDURE Read_QChannel(VAR QC : QChannel_Info);
  661.   BEGIN
  662.     rq_QChan.IOctl_Cmd := IOI_QCHAN_INFO;
  663.     rq_QChan.Addr_Mode := Red;
  664.     IOctl_In(Audio_Drive, 0, @rq_QChan,
  665.              SizeOf(IO_Inp_QChannel));
  666.     QC := (rq_QChan.qInfo);
  667.   END;
  668.  
  669.   FUNCTION IOctl_Out(Drive    : WORD;
  670.                      Unit_1   : BYTE;
  671.                      pRequest : pInteger;
  672.                      rqLen    : WORD) : WORD;
  673.   VAR
  674.     Regs : Registers;
  675.   BEGIN
  676.     rqOutp.IOCtl_nBytes      := rqLen;
  677.     rqOutp.IOCtl_xFer        := pInteger(pRequest);
  678.     rqOutp.IOctl_Rqh.rq_Unit := Unit_1;
  679.  
  680.     Regs.AX := $1510;
  681.     Regs.CX := Drive;
  682.     Regs.BX := Ofs(rqOutp);
  683.     Regs.ES := Seg(rqOutp);
  684.     Intr($2F, Regs);
  685.     IOctl_Out := (rqOutp.IOctl_Rqh.rq_Status);
  686.   END;
  687.  
  688.   PROCEDURE CD_Reset;
  689.   BEGIN
  690.     rq_Reset.IOctl_Cmd := IOO_RESET;
  691.     IOctl_Out(Audio_Drive, 0, @rq_Reset,
  692.               SizeOf(IO_Outp_Eject));
  693.   END;
  694.  
  695.   PROCEDURE Eject_CD;
  696.   BEGIN
  697.     rq_Eject.IOctl_Cmd := IOO_EJECT;
  698.     IOctl_Out(Audio_Drive, 0, @rq_Eject,
  699.               SizeOf(IO_Outp_Eject));
  700.   END;
  701.  
  702.   PROCEDURE Insert_CD;
  703.   BEGIN
  704.     rq_Insert.IOctl_Cmd := IOO_CLOSE_TRAY;
  705.     IOctl_Out(Audio_Drive, 0, @rq_Insert,
  706.               SizeOf(IO_Outp_Eject));
  707.   END;
  708.  
  709.   PROCEDURE SetVolume(Chan0, Chan1, Chan2, Chan3 : BYTE);
  710.   BEGIN
  711.     rq_Volume.IOctl_Cmd := IOI_AUDIOCHAN_INFO;
  712.     IOctl_In(Audio_Drive, 0, @rq_Volume,
  713.              SizeOf(IO_Inp_Audiochan_Info));
  714.  
  715.     rq_Volume.IOctl_Cmd := IOO_AUDIOCHAN_CTRL;
  716.     rq_Volume.Vol_Chan0 := Chan0;
  717.     rq_Volume.Vol_Chan1 := Chan1;
  718.     rq_Volume.Vol_Chan2 := Chan2;
  719.     rq_Volume.Vol_Chan3 := Chan3;
  720.     IOctl_Out(Audio_Drive, 0, @rq_Volume,
  721.               SizeOf(IO_Inp_Audiochan_Info));
  722.   END;
  723.  
  724.   PROCEDURE SetInput(Chan0, Chan1, Chan2, Chan3 : BYTE);
  725.   BEGIN
  726.     rq_Input.IOctl_Cmd := IOI_AUDIOCHAN_INFO;
  727.     IOctl_In(Audio_Drive, 0, @rq_Input,
  728.              SizeOf(IO_Inp_Audiochan_Info));
  729.     rq_Input.IOctl_Cmd := IOO_AUDIOCHAN_CTRL;
  730.     rq_Input.Inp_Chan0 := Chan0;
  731.     rq_Input.Inp_Chan1 := Chan1;
  732.     rq_Input.Inp_Chan2 := Chan2;
  733.     rq_Input.Inp_Chan3 := Chan3;
  734.     IOctl_Out(Audio_Drive, 0, @rq_Input,
  735.               SizeOf(IO_Inp_Audiochan_Info));
  736.   END;
  737.  
  738.   FUNCTION Play_Audio_1(Start    : CD_Addr;
  739.                         nSectors : LONGINT) : WORD;
  740.   VAR
  741.     Regs : Registers;
  742.   BEGIN
  743.     rq_Play.Start   := Start;
  744.     rq_Play.nFrames := nSectors;
  745.  
  746.     Regs.AX := $1510;
  747.     Regs.CX := Audio_Drive;
  748.     Regs.BX := Ofs(rq_Play);
  749.     Regs.ES := Seg(rq_Play);
  750.     Intr($2F, Regs);
  751.     Play_Audio_1 := (rq_Play.Play_rqh.rq_Status);
  752.   END;
  753.  
  754.   FUNCTION Play_Track(Tno : BYTE) : BOOLEAN;
  755.   BEGIN
  756.     IF (Tno <= Titles) THEN BEGIN
  757.       Play_Audio_1(Index[INTEGER(Tno)].Start,
  758.                    Index[INTEGER(Tno)].Frames);
  759.       Start_Play := Red2HSG(Index[INTEGER(Tno)].Start);
  760.       End_Play   := Red2HSG(Index[INTEGER(Tno)].Start) +
  761.                             Index[INTEGER(Tno)].Frames;
  762.       Play_Track := TRUE;
  763.     END ELSE
  764.       Play_Track := FALSE;
  765.   END;
  766.  
  767.   FUNCTION Play_Tracks(From, To_1 : LONGINT) : BOOLEAN;
  768.   VAR
  769.     Frames : LONGINT;
  770.   BEGIN
  771.     Frames := 0;
  772.     IF (INTEGER(From) > 0) AND (From <= To_1) AND
  773.        (To_1 <= Titles) THEN BEGIN
  774.       Frames := Red2HSG(Index[INTEGER(To_1)].Start) -
  775.                 Red2HSG(Index[INTEGER(From)].Start) +
  776.                         Index[INTEGER(To_1)].Frames;
  777.       Play_Audio_1(Index[INTEGER(From)].Start, Frames);
  778.       Start_Play  := Red2HSG(Index[INTEGER(From)].Start);
  779.       End_Play    := Start_Play + Frames;
  780.       Play_Tracks := TRUE;
  781.     END ELSE
  782.       Play_Tracks := FALSE;
  783.   END;
  784.  
  785.   FUNCTION Play_Track_Intro(Tno : INTEGER) : BOOLEAN;
  786.   BEGIN
  787.     IF (Tno >= 0) AND (Tno <= INTEGER(Titles)) THEN BEGIN
  788.       Play_Audio_1(Index[Tno].Start, 10*75);
  789.       Start_Play:=Red2HSG(Index[Tno].Start);
  790.       End_Play:=Red2HSG(Index[Tno].Start)+(10*75);
  791.       Play_Track_Intro := TRUE;
  792.     END ELSE
  793.       Play_Track_Intro := FALSE;
  794.   END;
  795.  
  796.   FUNCTION Stop_Audio_1 : WORD;
  797.   VAR
  798.     Regs : Registers;
  799.   BEGIN
  800.     Regs.AX := $1510;
  801.     Regs.CX := Audio_Drive;
  802.     Regs.BX := Ofs(rq_Stop);
  803.     Regs.ES := Seg(rq_Stop);
  804.     Intr($2F, Regs);
  805.     Stop_Audio_1 := (rq_Stop.Play_rqh.rq_Status);
  806.   END;
  807.  
  808.   FUNCTION Resume_Audio_1 : WORD;
  809.   VAR
  810.     Regs : Registers;
  811.   BEGIN
  812.     Regs.AX := $1510;
  813.     Regs.CX := Audio_Drive;
  814.     Regs.BX := Ofs(rq_Resume);
  815.     Regs.ES := Seg(rq_Resume);
  816.     Intr($2F, Regs);
  817.     Resume_Audio_1 := (rq_Resume.Play_rqh.rq_Status);
  818.   END;
  819.  
  820.   FUNCTION Skip_Audio(Frames : LONGINT) : WORD;
  821.   VAR
  822.     Skip_Delta : LONGINT;
  823.     Skip_To    : CD_Addr;
  824.     Tmp_Start  : LONGINT;
  825.     Stat_Audio : Audio_Status;
  826.     Dummy      : CD_Addr;
  827.   BEGIN
  828.     Read_QChannel(qInfo);
  829.     Tmp_Start := LONGINT ( LONGINT(qInfo.dMin) * 4500 +
  830.                            LONGINT(qInfo.dSec) *   75 +
  831.                            LONGINT(qInfo.dFrame) + Frames);
  832.     IF (Tmp_Start >= End_Play) THEN BEGIN
  833.       Skip_Audio := 0;
  834.       Exit;
  835.     END;
  836.     IF (Tmp_Start > Start_Play) THEN BEGIN
  837.       HSG2Red(Tmp_Start, Skip_To);
  838.       Skip_Delta := End_Play - Tmp_Start;
  839.       Stop_Audio_1;
  840.       Play_Audio_1(Skip_To, Skip_Delta);
  841.     END ELSE BEGIN
  842.       Stop_Audio_1;
  843.       HSG2Red(Start_Play, Dummy);
  844.       Play_Audio_1(Dummy, End_Play - Start_Play);
  845.     END;
  846.     Skip_Audio := 1;
  847.   END;
  848.  
  849.   FUNCTION Init_CDAudio : INTEGER;
  850.   VAR
  851.     Regs           : Registers;
  852.     Stat_Audio     : Audio_Status;
  853.     I              : INTEGER;
  854.     nDrives        : INTEGER;
  855.     Logical_Drives : ARRAY [0..25] OF CHAR;
  856.   BEGIN
  857.     Regs.AX := $1500;
  858.     Regs.BX := 0;
  859.     Intr($2F, Regs);
  860.     IF (Regs.BX = 0) THEN BEGIN
  861.       Init_CDAudio := -1;
  862.       Exit;
  863.     END;
  864.     nDrives := Regs.BX;
  865.     Regs.AX := $150D;
  866.     Regs.ES := Seg(Logical_Drives);
  867.     Regs.BX := Ofs(Logical_Drives);
  868.     Intr($2F, Regs);
  869.  
  870.     I := 0;
  871.     WHILE (I < nDrives) DO BEGIN
  872.       IF ((Get_Status(Logical_Drives[I]) AND
  873.            DATA_AND_AUDIO)) <> 0 THEN BEGIN
  874.         Audio_Drive := INTEGER(Logical_Drives[I]);
  875.         (* goto Break_1; *) Break;
  876.       END;
  877.       I := Succ(I);
  878.     END;
  879. (*  Break_1: *)
  880.     IF (I = nDrives) THEN BEGIN
  881.       Init_CDAudio := (-2);
  882.       Exit;
  883.     END;
  884.     Get_Header;
  885.  
  886.     I := 1;
  887.     WHILE (I <= 20) DO BEGIN
  888.       IF (INTEGER(Get_Media_Changed) < 128) THEN BEGIN
  889.         (* goto Break_2; *) Break;
  890.       END;
  891.       I := Succ(I);
  892.     END;
  893. (*  Break_2: *)
  894.     IF (INTEGER(Get_Media_Changed) > 128) THEN BEGIN
  895.       Init_CDAudio := (-3);
  896.       Exit;
  897.     END;
  898.  
  899.     Titles := Get_TOC;
  900.  
  901.     Read_Audio_Status(Stat_Audio);
  902.     End_Play     := Red2HSG(Stat_Audio.End_1);
  903.     Init_CDAudio := INTEGER(Titles);
  904.   END;
  905.  
  906.   FUNCTION Get_Titles : BYTE;
  907.   BEGIN
  908.     Get_Titles := Titles;
  909.   END;
  910.  
  911.   PROCEDURE Get_Len(Tno : CHAR; VAR Len : CD_Addr);
  912.   BEGIN
  913.     Len := Index[INTEGER(Tno)].Delta;
  914.   END;
  915.  
  916.   FUNCTION Get_Actual_Track : INTEGER;
  917.   BEGIN
  918.     Read_QChannel(qInfo);
  919.     Get_Actual_Track := ((INTEGER(qInfo.Tno) SHR 4)*10) +
  920.                          (INTEGER(qInfo.Tno) AND $0F);
  921.   END;
  922.  
  923.   PROCEDURE Get_Time_In_Track(T : QChannel_Info);
  924.   BEGIN
  925.     Read_QChannel(qInfo);
  926.     T := qInfo;
  927.   END;
  928.  
  929.   FUNCTION Get_Audio_Drive : CHAR;
  930.   BEGIN
  931.     Get_Audio_Drive := CHAR(Audio_Drive);
  932.   END;
  933.  
  934.  
  935. BEGIN
  936.   maxTitles := Init_CDAudio;
  937. END.
  938.  
  939.